#include "../include/node_data.h"
#include "../include/user_config.h"
#include "../include/saver.h"
#include <qdebug.h>

NodeData::NodeData(int id) : self_id(id), rank_order(-1)
{
	path_prefix = "Database\\node" + std::to_string(self_id) + "\\";
}

NodeData::~NodeData()
{
}

int NodeData::SelfID()
{
	return self_id;
}

void NodeData::pushBackDay(DayData day_data, int year, int month, int day)
{
	node_data[year][month][day] = day_data;
}

void NodeData::pushBackDay(DayData day_data, dateData date)
{
	node_data[date.Year][date.Month][date.Day] = day_data;
}

void NodeData::pushBackMoment(StampStruct stamp, bool PowerON, bool isTamp)
{
	HourMin temp_moment;
	temp_moment.hour = stamp.Hour;
	temp_moment.minute = stamp.Minute;
	temp_moment.PowerON = PowerON;
	temp_moment.isTamp = isTamp;
	if (node_data[stamp.Year][stamp.Month][stamp.Day].size() > 0)
	{
		if ((node_data[stamp.Year][stamp.Month][stamp.Day].end() - 1)->PowerON == PowerON)
			node_data[stamp.Year][stamp.Month][stamp.Day].erase(node_data[stamp.Year][stamp.Month][stamp.Day].end() - 1);
	}
	node_data[stamp.Year][stamp.Month][stamp.Day].push_back(temp_moment);
}

DayData NodeData::getDayData(int year, int month, int day)
{
	return node_data[year][month][day];
}

DayData NodeData::getDayData(dateData date)
{
	qDebug("get id_%d data: Year:%d-Month:%d-Day:%d", self_id, date.Year, date.Month, date.Day);
	return node_data[date.Year][date.Month][date.Day];
}

int NodeData::getRangeDateMin(dateData begin_date, dateData end_date)
{
	int total_min = 0;
	for (; begin_date <= end_date; begin_date++)
	{
		DayData temp_data = node_data[begin_date.Year][begin_date.Month][begin_date.Day];
		if (temp_data.size() == 0)
		{
			total_min += (thisDayisElectricAtFirst(begin_date) ? 24 * 60 : 0);
			continue;
		}
		for (int i = 0; i < temp_data.size(); i++)
		{
			if (!temp_data[i].PowerON)
			{
				if (i == 0)
					total_min += temp_data[i].hour * 60 + temp_data[i].minute;
				else
				{
					total_min += (temp_data[i].hour - temp_data[i - 1].hour) * 60 + temp_data[i].minute - temp_data[i - 1].minute;
				}
			}
			else
			{
				if (i == temp_data.size() - 1 && !(begin_date == user_config.end_date))
					total_min += (24 - temp_data[i].hour) * 60 + 0 - temp_data[i].minute;
			}
		}
	}

	return total_min;
}

bool NodeData::thisDayisElectricAtFirst(dateData date)
{
	date--;
	for (; user_config.begin_date <= date; date--)
	{
		if (node_data[date.Year][date.Month][date.Day].size() > 0)
		{
			return (node_data[date.Year][date.Month][date.Day].end() - 1)->PowerON;
		}
	}
	return false;
}

void NodeData::updateData(dateData begin_date, dateData end_date)
{
	int year_index = begin_date.Year;
	int month_index = begin_date.Month;
	for (; ((year_index - end_date.Year) * 12 + month_index - end_date.Month) != 1; )
	{
		std::string file_path = path_prefix + "Year" + std::to_string(year_index) +
			"\\Month" + std::to_string(month_index) + ".yaml";
		disk::getMonthYaml(node_data[year_index][month_index], file_path);
		if (++month_index == 13)
		{
			month_index = 1;
			year_index++;
		}
	}
}

void NodeData::delectData(dateData begin_date, dateData end_date)
{
	int year_index = begin_date.Year;
	int month_index = begin_date.Month;
	for (; ((year_index - end_date.Year) * 12 + month_index - end_date.Month) != 1; )
	{
		std::string file_path = path_prefix + "Year" + std::to_string(year_index) +
			"\\Month" + std::to_string(month_index) + ".yaml";
		disk::delectYaml(file_path);
		if (++month_index == 13)
		{
			month_index = 1;
			year_index++;
		}
	}
}

void NodeData::saveNodeHisData()
{
	HistoryData::iterator year_iter = node_data.begin();
	for (; year_iter != node_data.end(); year_iter++)
	{
		YearData::iterator month_iter = year_iter->second.begin();
		for (; month_iter != year_iter->second.end(); month_iter++)
		{
			std::string file_path = path_prefix + "Year" + std::to_string(year_iter->first) +
				"\\Month" + std::to_string(month_iter->first) + ".yaml";
			disk::saveMonthYaml(month_iter->second, file_path);
		}
	}
}

void NodeData::saveNodeHisData(int Year, int Month)
{
	std::string file_path = path_prefix + "Year" + std::to_string(Year) +
		"\\Month" + std::to_string(Month) + ".yaml";
	disk::saveMonthYaml(node_data[Year][Month], file_path);
}

void NodeData::qDebugHisData()
{
	qDebug() << "show node" << std::to_string(self_id).c_str() << "data:";
	HistoryData::iterator year_iter = node_data.begin();
	for (; year_iter != node_data.end(); year_iter++)
	{
		qDebug() << "Year: " << year_iter->first;
		YearData::iterator month_iter = year_iter->second.begin();
		for (; month_iter != year_iter->second.end(); month_iter++)
		{
			qDebug() << "\tMonth: " << month_iter->first;
			MonthData::iterator day_iter = month_iter->second.begin();
			for (; day_iter != month_iter->second.end(); day_iter++)
			{
				qDebug() << "\t\tDay: " << day_iter->first;
				DayData::iterator moment_iter = day_iter->second.begin();
				for (; moment_iter != day_iter->second.end(); moment_iter++)
				{
					qDebug() << "\t\t\t~";
					qDebug() << "\t\t\tHour" << moment_iter->hour;
					qDebug() << "\t\t\tMinute" << moment_iter->minute;
					qDebug() << "\t\t\tPowerON" << moment_iter->PowerON;
				}
			}
		}
	}
}
